package com.zhj.springbootinit.bizmq;

import com.rabbitmq.client.Channel;
import com.zhj.springbootinit.common.ErrorCode;
import com.zhj.springbootinit.exception.BusinessException;
import com.zhj.springbootinit.exception.ThrowUtils;
import com.zhj.springbootinit.manager.AIManager;
import com.zhj.springbootinit.model.entity.Chart;
import com.zhj.springbootinit.service.ChartService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;

@Component
@Slf4j
public class BIMessageConsumer {

    @Resource
    private ChartService chartService;

    @Resource
    private AIManager aiManager;

    @RabbitListener(queues = {BIMQConstant.BI_MQ_QUEUE}, ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        log.info("receive message = {}", message);
        if (StringUtils.isBlank(message)) {
            try {
                channel.basicNack(deliveryTag, false, false);
            } catch (IOException e) {
                log.info("io 错误 = {}", e.getMessage());
            }
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "消息队列中接受的信息为空");
        }
        long chartId = Long.parseLong(message);
        Chart chart = chartService.getById(chartId);
        if (chart == null) {
            channel.basicNack(deliveryTag, false, false);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "图表对象为空");
        }

        Chart updateChart = new Chart();
        updateChart.setId(chart.getId());
        updateChart.setStatus("running");

        // 修改状态
        boolean b = chartService.updateById(updateChart);
        if (!b) {
            channel.basicNack(deliveryTag, false, false);
            handleUpdateChartError(chart.getId(), "Chart更新状态失败");
            return;
        }

        Chart aiChart = chartService.getById(chartId);
        if (aiChart == null) {
            channel.basicNack(deliveryTag, false, false);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取ai处理的图表对象为空");
        }

        // 正式调用AI接口
        String resultText = aiManager.getMessageByAI(buildUserInputByIO(aiChart));

        String[] split = resultText.split("【【【【【");
        if (split.length < 3) {
            channel.basicNack(deliveryTag, false, false);
            ThrowUtils.throwIf(true, ErrorCode.OPERATION_ERROR, "AI响应错误，返回参数异常");
        }

        String codeData = handleCodeData(split[1]); // echarts代码数据
        String resultData = split[2].trim(); // 分析结果数据

        Chart resultChart = new Chart();
        resultChart.setId(chart.getId());
        resultChart.setGenChart(codeData);
        resultChart.setGenResult(resultData);
        // todo 建议定义状态为枚举值
        resultChart.setStatus("succeed");
        boolean b1 = chartService.updateById(resultChart);
        if (!b1) {
            channel.basicNack(deliveryTag, false, false);
            handleUpdateChartError(chart.getId(), "存储AI处理结果失败");
        }

        // 消息确认
        channel.basicAck(deliveryTag, false);
    }

    private String buildUserInputByIO(Chart chart) {
        String goal = chart.getGoal();
        String chartType = chart.getChartType();
        String chartData = chart.getChartData();

        StringBuilder userInput = new StringBuilder();

        // 2.分析目标
        userInput.append("分析需求:").append("\n");

        String targetText = goal;

        if (StringUtils.isNotBlank(chartType)) {
            targetText += ",请使用" + chartType;
        }

        userInput.append(targetText).append("\n");

        // 3.数据
        userInput.append("数据:").append("\n").append(chartData);

        return userInput.toString();
    }

    private void handleUpdateChartError(Long chartId, String execMessage) {
        Chart chart = new Chart();
        chart.setId(chartId);
        chart.setStatus("fail");
        chart.setExecMessage(execMessage);
        boolean updateResult = chartService.updateById(chart);
        if (!updateResult) {
            log.error("更新图表失败状态失败:" + chartId + "," + execMessage);
        }
    }

    private String handleCodeData(String str) {
        if (StringUtils.isNotBlank(str)) {
            int start = str.indexOf("{");
            int end = str.lastIndexOf("}");
            return str.substring(start, end + 1);
        }
        return "";
    }
}
